package com.getan.boot.common;

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.ToString;

import java.util.function.Function;

/**
 * 接受 ResponseCode 的数据交互格式
 *
 * @author Bruce.Gong
 * @since 1.0.0-SNAPSHOT
 */
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@Data
public class ResponseCodeData<T> extends ResponseData<T> {

    /**
     * 提示码
     */
    private String code;

    /**
     * @inheritDoc
     */
    @Override
    public ResponseCodeData<T> ok() {
        super.ok();
        return this;
    }

    /**
     * @inheritDoc
     */
    @Override
    public ResponseCodeData<T> ok(T data) {
        super.ok(data);
        return this;
    }

    /**
     * @inheritDoc
     */
    @Override
    public ResponseCodeData<T> ok(String info, T data) {
        super.ok(info, data);
        return this;
    }

    /**
     * @inheritDoc
     */
    @Override
    public ResponseCodeData<T> fail() {
        super.fail();
        return this;
    }

    /**
     * @inheritDoc
     */
    @Override
    public ResponseCodeData<T> fail(String info) {
        super.fail(info);
        return this;
    }

    /**
     * @inheritDoc
     */
    public ResponseCodeData<T>
    fail(String code, String info) {
        this.code = code;
        super.fail(info);
        return this;
    }

    /**
     * @inheritDoc
     */
    @Override
    public ResponseCodeData<T> fail(ResponseCode errorCode, Object... params) {
        this.code = errorCode.getCode();
        super.fail(errorCode, params);
        return this;
    }

    /**
     * @inheritDoc
     */
    public ResponseCodeData<T> fail(ResponseCodeData<?> response) {
        this.code = response.getCode();
        this.fail(response.getCode(), response.getMessage());
        return this;
    }

    /**
     * @inheritDoc
     */
    @Override
    public ResponseCodeData<T> fail(ResponseCodeAccessor exception) {
        return this.fail(exception.getResponseCode());
    }

    /**
     * 根据 ResponseCodeData 的结果，转换数据类型
     *
     * @param queryFunction 转换函数
     * @return 校验结果
     */
    public <E> ResponseCodeData<E> ifSuccess(Function<T, E> queryFunction) {
        if (isOk()) {
            return ResponseBuilder.ok(queryFunction.apply(getData()));
        } else {
            return ResponseBuilder.fail(this);
        }
    }

}
